﻿#include "ThreeDSurfacePlotWindow.h"

#include <QDebug>
#include <tuple>
#include <QSplitter>
#include <QHBoxLayout>
#include <QListWidgetItem>

#include <vtkPointSet.h>
#include <vtkDataSet.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkTextProperty.h>
#include <vtkScalarBarActor.h>
#include <vtkStructuredGrid.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkMapper.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkPolyData.h>
#include <vtkTextActor.h>
#include <vtkCubeAxesActor.h>

#include "FieldGraphGenerator.h"
#include "ThreeDSurfacePlotSidebarSettings.h"
#include "ThreeDSurfacePlotSettingDialog.h"
#include "InfomationGraph3DBasical.h"
#include "PropPickerCallbackHander.h"
#include "BaseModule/IBaseSignal.h"
#include "ThreeDSurfacePlotSettingData.h"
#include "ThreeDSurfacePlotSidebarData.h"
#include "FarFieldDataGenerator.h"
#include "AnimationSettingData.h"
#include "CommonFunction.h"
#include "TextFileParser.h"
#include <vtkFieldData.h>
#include <vtkStringArray.h>
#include <vtkScalarBarWidget.h>
#include <vtkTransform.h>
#include "FramelessDragableTableWidget.h"
#include "DataClipperGenerator.h"
#include "BaseModule/GlobalHelper.h"
#include "PoseSettingData.h"
#include "PoseSettingDialog.h"
#include "TDSPDefaultInteractorStyle.h"
#include "BaseWidget/IdaDialogMsg.h"
#include "GeomtryActorGenerator.h"
#include "DataClipperFilter.h"
#include "PipelineManager.h"
#include "DataTransformFilter.h"
#include "MainWindowSignalHandler.h"
#include "BaseWidget/IWidgetSignal.h"
#include "DataManager/WindowTotalData.h"
#include "AnimationTooBarInfoData.h"
#include "FieldScalarBarGenerator.h"
#include "ScalarBarSettingData.h"
#include <vtkCamera.h>
#include <vtkLookupTable.h>

namespace pst
{
    ThreeDSurfacePlotWindow::ThreeDSurfacePlotWindow(QWidget* parent, int windowId)
        : Graph3DWindowBase(parent)
        , m_sidebarSettings(new ThreeDSurfacePlotSidebarSettings(this))
        , m_mainSettingDialog(new ThreeDSurfacePlotSettingDialog(this))
        //, m_geometrySettingData(new TDSPGeometrySettingData(this))
        , m_cubeAxesSettingData(new TDSPCubeAxesActorSettingData(this))
        , m_isAnimationDataPrepared(false)
        , m_windowId(windowId)
        , m_defaultInteractorStyle(vtkSmartPointer<TDSPDefaultInteractorStyle>::New())

    {
        m_mainSettingDialog->setMainWindowId(m_windowId);
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->setContentsMargins(0, 0, 0, 0);
        layout->setStretch(0, 1);
        layout->setStretch(1, 0);

        //QSplitter* splitter = new QSplitter(Qt::Horizontal, this);
        layout->addWidget(this->m_qvtkWidget);
        layout->addWidget(m_sidebarSettings);
        //splitter->setSizes({ 3000, 1000 });
        //layout->addWidget(splitter);

        m_markerDataTable->hide();

        m_doubleClickCallback = vtkSmartPointer<PropPickerCallbackHander>::New();
        this->m_renderWindow3D->GetInteractor()->AddObserver(vtkCommand::LeftButtonDoubleClickEvent, m_doubleClickCallback);

        m_sidebarSettings->setMainWiondowId(m_windowId);
        initScalarBarSettingConnection();
        initSidebarSettingConnection();

        setInteractorStlyleToDefault();
        connect(m_defaultInteractorStyle, &TDSPDefaultInteractorStyle::signal_rightButtonUpEvent, this, &ThreeDSurfacePlotWindow::slot_rightButtonUpEvent);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_renameCheck,this, &ThreeDSurfacePlotWindow::slot_renameCheck);
        connect(m_mainSettingDialog, &ThreeDSurfacePlotSettingDialog::signal_checkResultNameIsValid,this, &ThreeDSurfacePlotWindow::slot_checkResultNameIsValid);
        connect(IWidgetSignalInstance, &BaseWidget::IWidgetSignal::signal_closeTree, this, &ThreeDSurfacePlotWindow::slot_closeTree);

        m_defaultInteractorStyle->SetDefaultRenderer(m_render3D);
        m_defaultInteractorStyle->SetRenderWindowWidget(m_qvtkWidget);
        m_renderWindow3D->GetInteractor()->SetInteractorStyle(m_defaultInteractorStyle);
    }

    void ThreeDSurfacePlotWindow::updateClipper(bool activeClipper)
    {
        for (auto info : m_graphInfoList)
        {
            if (info->m_fieldGraphGenerator == nullptr)
            {
                qDebug() << "SurfaceElectricFieldMapWindow::updateClipper info->m_fieldGraphGenerator == nullptr";
                return;
            }
            if (info->m_dataClipperFilter == nullptr)
            {
                info->m_dataClipperFilter = new DataClipperFilter();

                auto filterManager = info->m_fieldGraphGenerator->GetScalarPipelineManager();
                filterManager->AddFilter("Clipper", info->m_dataClipperFilter);
            }

            //info->m_dataClipperFilter->setInput(info->m_data);
            info->m_dataClipperFilter->setEnabled(activeClipper);
            info->m_dataClipperFilter->setPlaneNormalDirection(
                m_planeNormalDirection[0], m_planeNormalDirection[1], m_planeNormalDirection[2]);
            info->m_dataClipperFilter->setPlaneOrigin(
                m_planeOrigin[0], m_planeOrigin[1], m_planeOrigin[2]);
            //info->m_dataClipperGenerator->setLookupTable(info->m_fieldGraphGenerator->GetScalarsLookupTable());
            //info->m_dataClipperFilter->update();
            //m_render3D->AddActor(info->m_dataClipperGenerator->getClipActor());

            info->m_fieldGraphGenerator->UpdateScalarFieldActor();
            ////同步透明度和缩放
            //for (auto i : m_dataMap)
            //{
            //    if (i.first == info)
            //    {
            //        auto mainSettingData = i.second;
            //        auto resultDataSettingData = mainSettingData->getResultDataSettingData();
            //        info->m_dataClipperGenerator->getClipActor()->GetProperty()->SetOpacity(1 - resultDataSettingData->getResultDataTransparency() / 100.);
            //        info->m_dataClipperGenerator->getClipActor()->SetScale(resultDataSettingData->getResultDataScaleFactor());
            //    }
            //}

            ////生成裁剪平面的actor
            //QList<vtkDataSet*> dataList;
            //for (auto i : m_curveMap)
            //{
            //    if (i->m_actor->GetVisibility() /*|| info->m_dataClipperGenerator->getClipActor()->GetVisibility()*/)
            //    {
            //        vtkDataSet* dataSet = vtkDataSet::SafeDownCast(i->m_dataTransformFilter->getOutput());
            //        dataList.append(dataSet);
            //    }
            //    if (i->m_geomtryActorGenerator != nullptr && i->m_geomtryActorGenerator->getActor()->GetVisibility())//考虑几何
            //    {
            //        dataList.append(i->m_geomtryActorGenerator->getGeometryPolyData());
            //    }
            //}
            ////auto isSuc = this->CreateExpandedPlaneActor(actorList, m_planeNormalDirection, m_planeOrigin);
            //auto isSuc = this->CreateExpandedPlaneActor(dataList, m_planeNormalDirection, m_planeOrigin);
            //if (!isSuc)
            //{
            //    return;
            //}
            //m_render3D->AddActor(m_clipperPlaneActor);

            auto item = info->m_sidebarItem;
            if (item == nullptr)
            {
                return;
            }
            slot_showHideItemActor(item);
        }

        updateClipperPlaneActor();
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::updateClipperPlaneActor()
    {
        //生成裁剪平面的actor
        QList<vtkDataSet*> dataList;
        for (auto i : m_graphInfoList)
        {
            if (i->m_actor->GetVisibility() /*|| info->m_dataClipperGenerator->getClipActor()->GetVisibility()*/)
            {
                dataList.append(i->m_actor->GetMapper()->GetInput());
            }
            if (i->m_geomtryActorGenerator != nullptr && i->m_geomtryActorGenerator->getActor()->GetVisibility())//考虑几何
            {
                dataList.append(i->m_geomtryActorGenerator->getGeometryPolyData());
            }
        }
        //auto isSuc = this->CreateExpandedPlaneActor(actorList, m_planeNormalDirection, m_planeOrigin);
        auto isSuc = this->CreateExpandedPlaneActor(dataList, m_planeNormalDirection, m_planeOrigin);
        if (!isSuc)
        {
            return;
        }
        m_render3D->AddActor(m_clipperPlaneActor);
    }

    void ThreeDSurfacePlotWindow::setWindowID(int windowID)
    {
        m_windowId = windowID;
    }
    int ThreeDSurfacePlotWindow::getWindowID() const
    {
        return m_windowId;
    }

    void ThreeDSurfacePlotWindow::setWindowUniversalID(int windowUniversalID)
    {
        m_windowUniversalID = windowUniversalID;
    }
    int ThreeDSurfacePlotWindow::getWindowUniversalID() const
    {
        return m_windowUniversalID;
    }

    QDomElement& ThreeDSurfacePlotWindow::writeToProjectFile(QDomDocument* doc, QDomElement* element, bool isdiso)
    {
        QDomElement _ThreeDSurfacePlotWindowDataRoot = doc->createElement("GraphWindow");
        QDomAttr _WindowUniversalIDattr = doc->createAttribute("WindowUniversalID");
        _WindowUniversalIDattr.setValue(QString::number(m_windowUniversalID));
        _ThreeDSurfacePlotWindowDataRoot.setAttributeNode(_WindowUniversalIDattr);
        QDomAttr _idattr = doc->createAttribute("WindowID");
        _idattr.setValue(QString::number(m_windowId));
        _ThreeDSurfacePlotWindowDataRoot.setAttributeNode(_idattr);
        QDomAttr typeattr = doc->createAttribute("WindowType");
        typeattr.setValue("ThreeDSurfacePlotWindow");
        _ThreeDSurfacePlotWindowDataRoot.setAttributeNode(typeattr);

        element->appendChild(_ThreeDSurfacePlotWindowDataRoot);

         m_cubeAxesSettingData->writeToProjectFile(doc, &_ThreeDSurfacePlotWindowDataRoot, true, isdiso);
        for (auto _graphDataInfo : m_graphInfoList)
        {
            _graphDataInfo->writeToProjectFile(doc, &_ThreeDSurfacePlotWindowDataRoot, GraphType::ThreeDSurfacePlot, isdiso);
        }
        writeToProjectFile3DWindowBase(doc, &_ThreeDSurfacePlotWindowDataRoot);

        return _ThreeDSurfacePlotWindowDataRoot;
    }

    void ThreeDSurfacePlotWindow::readFromProjectFile(QDomElement* element, bool isdiso)
    {
        m_windowUniversalID = element->attribute("WindowUniversalID").toInt();
        int id = element->attribute("WindowID").toInt();
        m_windowId = id;

        auto _TDSPCubeAxesActorSettingDataFromWindowNodeList = element->elementsByTagName("TDSPCubeAxesActorSettingDataFromWindow");
        m_cubeAxesSettingData->readFromProjectFile(&_TDSPCubeAxesActorSettingDataFromWindowNodeList.at(0).toElement(), true,isdiso);

        auto _infosNodeList = element->elementsByTagName("InfomationGraph3DBasical");
        auto _infosCount = _infosNodeList.count();
        if (_infosCount == 0)
            return;
        for (int i = 0; i < _infosCount; i++)
        {
            QDomElement elemModel = _infosNodeList.at(i).toElement();
            auto _ProjectTreeSourceItemID = elemModel.attribute("ProjectTreeSourceItemID").toInt();
            if (_ProjectTreeSourceItemID != -1)
            {
                // 通过info的projectTreeItem到mainwindow构造完整的info信息
                auto info = MainWindowSignalHandlerInstance->BuildCompleteGraph3DInfoByProjectTreeItem(_ProjectTreeSourceItemID, GraphType::ThreeDSurfacePlot);
                if (info != nullptr)
                {
                    info->m_currentFrequencyIndex = elemModel.attribute("CurrentFrequencyIndex").toInt();
                    info->m_valueGroupNameIndex = elemModel.attribute("ValueGroupNameIndex").toInt();
                    info->m_valueComponentIndex = elemModel.attribute("ValueComponentIndex").toInt();

                    auto _geometryFileNameStr = elemModel.attribute("GeometryFileName");
                    info->m_geometryFileName = _geometryFileNameStr.split(";");
                    for (auto& _filePath : info->m_geometryFileName)
                    {
                        auto isSuc = GlobalHelperInstance->CurrentInstallationDirectoryPathConversion(_filePath);
                    }

                    info->m_graph = this;
                    this->addGraph3D(info);

                    info->readFromProjectFile(&elemModel, GraphType::ThreeDSurfacePlot, isdiso);
                    slot_updateSetting(info->m_threeDSurfacePlotSettingData);

                    auto _curveNameListWidget = m_sidebarSettings->getCurveNameListWidget();
                    emit IBaseSignalInstance->signal_threeDSurfacePlotSidebarCurveNameClicked(m_windowId, {_curveNameListWidget->row(info->m_sidebarItem)});
                    emit IBaseSignalInstance->signal_threeDSurfacePlotSidebarFrequencyChanged(m_windowId, info->m_TDSPSidebarData->getCurrentFrequencyIndex());
                    emit IBaseSignalInstance->signal_threeDSurfacePlotSidebarResultDataChanged(m_windowId, info->m_TDSPSidebarData->getCurrentValueGroupNameIndex());
                    emit IBaseSignalInstance->signal_threeDSurfacePlotSidebarDataOprationChanged(m_windowId, info->m_TDSPSidebarData->getIsLog(),info->m_TDSPSidebarData->getIsNormalize());
                    emit IBaseSignalInstance->signal_threeDSurfacePlotSidebarCurveNameItemCheckStateChanged(m_windowId, {_curveNameListWidget->row(info->m_sidebarItem)}, info->m_TDSPSidebarData->getIsShowActor());
                    emit IBaseSignalInstance->signal_threeDSurfaceCurveDataFileterRadioButtonClicked(m_windowId, info->m_TDSPSidebarData->getCurrentComponentIndex());
                }
            }
        }
        readFromProjectFile3DWindowBase(element);
    }

    void ThreeDSurfacePlotWindow::addGraph3D(InfomationGraph3DBasical* info)
    {
        auto reader = static_cast<TextFileParser*>(info->m_reader);
        if (reader == nullptr)
        {
            return;
        }
        m_graphInfoList.append(info);
        if (!GlobalHelperInstance->getIsOpenProject())
            info->m_informationID = WindowTotalDataInstance->getGraph3DInformationMaxID();
        WindowTotalDataInstance->appendInfomationGraph3DBasical(info);

        vtkNew<vtkPolyData> resultData;
        vtkSmartPointer<vtkTable> tableToExport;
        QString errorMsg;

        int groupValueIndex = info->m_valueGroupNameIndex;
        int componentValueIndex = info->m_valueComponentIndex;

        int realIndex = reader->getRealValueIndex(groupValueIndex, componentValueIndex);

        auto isOk = info->m_farFieldDataGenerator->getDataSetByFreqency(info->m_currentFrequencyIndex,
            false, false, resultData, realIndex, errorMsg, tableToExport);
        if (!isOk)
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI(errorMsg);
            return;
        }
        info->m_tableToExport = tableToExport;
        // m_addedFarFieldData.append(resultData);

        // qDebug() << "resultData = ";
        // resultData->Print(std::cout);

        // vtkNew<vtkStructuredGridWriter> writer;
        // writer->SetInputData(resultData);
        // QString s = "D:/resultData" + QString::number(fre) + ".vtk";
        // writer->SetFileName(s.toStdString().c_str());
        // writer->Write();
        // info.m_reader = textFileParser;
        // info.m_grapgType = GraphType::ThreeDSurfacePlot;
        // info.m_filePath = textFileParser->GetFileName();

        info->m_data = resultData;

        // 添加曲线名字到侧边栏
        //info->m_name = info->m_name + "_" + QString::number(++graphNum);
        QListWidgetItem* item = m_sidebarSettings->addData(info);
        info->m_sidebarItem = item;
        // InfomationGraph3DBasical* currentInfo = m_curveMap[item];

        auto fieldGraphGenerator = new FieldGraphGenerator(this);
        info->m_fieldGraphGenerator = fieldGraphGenerator;
        // m_currentFieldGraphGenerator = fieldGraphGenerator;
        fieldGraphGenerator->SetInputDataSet(info->m_data);
        //fieldGraphGenerator->SetScalarsScalarBarWidgetInteractor(m_renderWindow3D->GetInteractor());

        // 获取标量场和矢量场
        auto pointArray = fieldGraphGenerator->GetPointsArrayIndexAndNames();
        auto cellArray = fieldGraphGenerator->GetCellsArrayIndexAndNames();
        for (int i = 0; i < pointArray.size(); i++)
        {
            // 标量场
            m_allScalarFieldArray.push_back(pointArray[i]);
            // 矢量场
            if (pointArray[i].arrayComponent == 3)
            {
                m_allVectorFieldArray.push_back(pointArray[i]);
            }
        }
        for (int i = 0; i < cellArray.size(); i++)
        {
            // 标量场
            m_allScalarFieldArray.push_back(cellArray[i]);
            // 矢量场
            if (cellArray[i].arrayComponent == 3)
            {
                m_allVectorFieldArray.push_back(cellArray[i]);
            }
        }

        if (m_allScalarFieldArray.isEmpty())
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI("No scalar field found!");
            return;
            // m_scalarDataActor = fieldGraphGenerator->GetGeometryActor();
        }

        // 使用第一个标量场
        const auto& currentField = m_allScalarFieldArray.at(0);
        auto isSetSuccess = fieldGraphGenerator->SetActiveScalarAttribute(
            currentField.arrayIndex, currentField.type, 0);
        if (!isSetSuccess)
        {
            return;
        }
        fieldGraphGenerator->UpdateScalarFieldActor();
        auto scalarDataActor = fieldGraphGenerator->GetScalarsFieldActor();
        m_render3D->AddActor(scalarDataActor);
        //auto scalarBarActor = fieldGraphGenerator->GetScalarsFieldScalarBarActor();
        //m_render3D->AddActor(scalarBarActor);
        info->m_actor = scalarDataActor;
        int _mapSettingDataID = -1;
        if (!GlobalHelperInstance->getIsOpenProject())
            _mapSettingDataID = WindowTotalDataInstance->getThreeDSurfacePlotMainSettingDataMaxID();
        ThreeDSurfacePlotSettingData* data = new ThreeDSurfacePlotSettingData(this, _mapSettingDataID);
        TDSPResultDataSettingData* resultDataSettingData = new TDSPResultDataSettingData(this);
        data->setResultDataSettingData(resultDataSettingData);
        //data->setGeometrySettingData(m_geometrySettingData);
        data->setCubeAxesActorSettingData(m_cubeAxesSettingData);

        // 设置颜色条
        auto dataType = info->m_resultType;
        auto scalarBarType = getScalarBarType(dataType);
        if (!m_scalarBarGeneratorMap.contains(scalarBarType))
        {
            m_scalarBarGeneratorMap[scalarBarType] = new FieldScalarBarGenerator(m_render3D, this);
            m_eachTypeGraphCount[scalarBarType] = 1;
            info->m_graphIDFromType = 1;
            // 创建双击事件回调
            m_doubleClickCallback->addCallbackObjectSlot(m_scalarBarGeneratorMap[scalarBarType]->getScalarBarActor(), this, "slot_scalarBarDoubleClicked");
            //qDebug() << "m_scalarBarGeneratorMap[dataType]->getScalarBarActor()" << m_scalarBarGeneratorMap[scalarBarType]->getScalarBarActor();
        }
        else
        {
            m_eachTypeGraphCount[scalarBarType] += 1;
            info->m_graphIDFromType = m_eachTypeGraphCount[scalarBarType];
        }

        auto columeType = GetResultDataTypeAsString(dataType, false);

        auto scalarBarGenerator = m_scalarBarGeneratorMap[scalarBarType];
        ScalarBarSettingData* scalarBarSettingData = scalarBarGenerator->getScalarBarSettingData();
        data->setScalarBarSettingData(scalarBarSettingData);
        scalarBarSettingData->setScalarBarTitle(columeType);

        info->m_fieldScalarBarGenerator = scalarBarGenerator;

        scalarBarGenerator->addGraph(fieldGraphGenerator);
        info->m_scalarBar = scalarBarGenerator->getScalarBarActor();

        ////设置初始值 scalarBar
        // vtkScalarBarActor* scalarBarActor = info->m_fieldGraphGenerator->GetScalarsFieldScalarBarActor();
        //slot_scalarBarFontTypeChanged(scalarBarActor, "宋体");
        //auto titleColor = scalarBarActor->GetTitleTextProperty()->GetColor();
        //QColor color;
        //color.setRgbF(titleColor[0], titleColor[1], titleColor[2]);
        //auto range = info->m_fieldGraphGenerator->GetCurrentScalarBarRange(FieldGraphGenerator::FieldType::SCALARS);

        //m_mainSettingDataId++;
        //TDSPScalarBarSettingData* scalarBarSettingData = new TDSPScalarBarSettingData(this);
        //TDSPResultDataSettingData* resultDataSettingData = new TDSPResultDataSettingData(this);
        //data->setScalarBarSettingData(scalarBarSettingData);
        //data->setGeometrySettingData(m_geometrySettingData);
        //data->setResultDataSettingData(resultDataSettingData);

        //auto scalarBarSetting = data->getScalarBarSettingData();
        //scalarBarSetting->setScalarBarOriginalMinRange(range[0]);
        //scalarBarSetting->setScalarBarOriginalMaxRange(range[1]);
        //scalarBarSetting->setScalarBarMinValue(range[0]);
        //scalarBarSetting->setScalarBarMaxValue(range[1]);
        //scalarBarSetting->setScalarBarFontSize(24);
        //scalarBarSetting->setScalarBarIsShowTitle(true);
        //scalarBarSetting->setScalarBarTitle(scalarBarActor->GetTitle());
        //scalarBarSetting->setScalarBarTitleColor(color);
        //scalarBarActor->GetTitleTextProperty()->SetFontSize(24);

        //scalarBarActor->Modified();
        //m_dataMap.append(qMakePair(info, data));
        info->m_threeDSurfacePlotSettingData = data;

        ////设置初始值 几何体
        if (info->m_geometryFileName.empty()) //几何路径为空
        {
            data->setGeometrySettingData(nullptr);
            info->m_geomtryActorGenerator = nullptr;
        }
        else
        {
            std::tuple<QStringList, QObject*, GeomtryActorGenerator*> existGeometryTuple;
            if (isContainGeometryPath(m_geometrySettingTupleList, info->m_geometryFileName, existGeometryTuple))
            {
                auto geometrySettingData = qobject_cast<TDSPGeometrySettingData*>(std::get<1>(existGeometryTuple));
                data->setGeometrySettingData(geometrySettingData);
                info->m_geomtryActorGenerator = std::get<2>(existGeometryTuple);
            }
            else
            {
                auto geometrySettingData = new TDSPGeometrySettingData(this);
                data->setGeometrySettingData(geometrySettingData);
                GeomtryActorGenerator* generator = new GeomtryActorGenerator(this);
                generator->setFileNameList(info->m_geometryFileName);
                generator->getActor()->SetVisibility(0);
                info->m_geomtryActorGenerator = generator;
                m_render3D->AddActor(generator->getActor());
                m_geometrySettingTupleList.append(std::make_tuple(info->m_geometryFileName, geometrySettingData, generator));
            }
        }

        // 生成侧边栏数据
        generateSidebarSettingData(item, info);
        QSignalBlocker bl(m_sidebarSettings->getCurveNameListWidget());
        item->setText(getSidebarDataFromNameItem(item)->getGraphName());
        item->setToolTip(getSidebarDataFromNameItem(item)->getGraphName());
        info->m_name = getSidebarDataFromNameItem(item)->getGraphName();

        /// 设置初始值 结果数据Actor
        auto resultDataSetting = data->getResultDataSettingData();
        resultDataSetting->setResultDataName(info->m_name);
        resultDataSetting->setResultDataTransparency(0);
        resultDataSetting->setResultDataScaleFactor(1.0);

        //更新颜色条单位和DB
        updateDBAndUnitData();

        // 姿态设置
        if (info->m_poseSettingData == nullptr)
        {
            PoseSettingData* poseSettingData = new PoseSettingData(this);
            info->m_poseSettingData = poseSettingData;
        }
        updateActorPosition(info);

        // 创建双击事件回调
        //m_doubleClickCallback->addCallbackObjectSlot(scalarBarActor, this, "slot_scalarBarDoubleClicked");

        //if (m_isActiveClip)
        //{
        //    updateClipper(true);
        //}
        bool _noUse = false;
        updateClipperAndGeometry(m_isActiveClip, m_isShowingGeometry, _noUse);
        //m_render3D->ResetCamera();
        //m_renderWindow3D->Render();
        updateAnimationButtonState();
        updateCubeAxesActor(m_cubeAxesSettingData->getVisibility());
        //设置动图总数据量
        auto freList = info->m_farFieldDataGenerator->getFreqencyList();
        info->m_VarValueList = freList;

        info->m_geometryFileName = reader->GetGeometryFileName();
        this->setCameraToIsometric();
    }

    void ThreeDSurfacePlotWindow::setActiveAnimation(bool active)
    {
        initAnimationInfoTextActor();
        auto widget = m_sidebarSettings->getCurveNameListWidget();
        if (m_animationType == 0) // 动数据
        {
            m_dataTimer->setInterval(1000. / m_animationSettingData->frameRate() / m_animationSpeed);

            if (!active)
            {
                m_dataTimer->stop();
                widget->setFocusPolicy(Qt::StrongFocus);
                widget->setSelectionMode(QAbstractItemView::SingleSelection);
                //m_sidebarSettings->setControlPanelEditable(true);
                connectSignalsAndSlots();
                //m_sidebarSettings->slot_curveNameClicked();
                m_sidebarSettings->setControlPlaneToAnimationState(false);

            }
            else
            {
                prepareAnimationData();
                m_dataTimer->start();
                widget->setFocusPolicy(Qt::NoFocus);
                widget->setSelectionMode(QAbstractItemView::NoSelection);
                //m_sidebarSettings->setControlPanelEditable(false);
                disconnectSignalsAndSlots();
                m_sidebarSettings->setControlPlaneToAnimationState(true);

                MainWindowSignalHandler::getInstance()->setToolButtonExportMotionGraphState(false);
                if (m_isExportingAnimation)
                {
                    emit IBaseSignalInstance->signal_UpdateStatusBarInformation(QStringLiteral("导出动图正在进行中..."), true);
                    QCoreApplication::processEvents();
                }
            }
        }

        else if (m_animationType == 1) // 动相机
        {
            if (!active)
            {
                m_cameraTimer->stop();
                //m_sidebarSettings->setControlPanelEditable(true);
                widget->setFocusPolicy(Qt::StrongFocus);
                widget->setSelectionMode(QAbstractItemView::SingleSelection);
                connectSignalsAndSlots();
                //m_sidebarSettings->slot_curveNameClicked();
                m_sidebarSettings->setControlPlaneToAnimationState(false);
                MainWindowSignalHandler::getInstance()->setToolButtonExportMotionGraphState(true);
            }
            else
            {
                m_animationCameraAngle = 0.0;
                m_animationCameraCount = 0;
                m_cameraTimer->start();
                //m_sidebarSettings->setControlPanelEditable(false);
                widget->setFocusPolicy(Qt::NoFocus);
                widget->setSelectionMode(QAbstractItemView::NoSelection);
                disconnectSignalsAndSlots();
                m_sidebarSettings->setControlPlaneToAnimationState(true);

                MainWindowSignalHandler::getInstance()->setToolButtonExportMotionGraphState(false);
                if (m_isExportingAnimation)
                {
                    emit IBaseSignalInstance->signal_UpdateStatusBarInformation(QStringLiteral("导出动图正在进行中..."), true);
                    QCoreApplication::processEvents();
                }
            }
        }

        m_animationInfoTextActor->SetVisibility(active);
        emit IWidgetSignalInstance->signal_setShowAnimationTextWidget(active);

        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::exportAnimationData(const QString& path)
    {
        m_isExportingAnimation = true;
        m_loopCount = 0;
        m_animationImageList.clear();
        m_exportAnimationPath = path;
        m_isBeginExportAnimation = true;

        if (m_animationType == 0) // 动数据
        {
            prepareAnimationData();
            setActiveAnimation(true);

            for (auto info : m_graphInfoList)
            {
                info->m_lastFrameIndexBeforeExportAnimation = info->m_currentAnimationIndex;
            }
        }
        else if (m_animationType == 1) // 动相机
        {
            setActiveAnimation(true);
        }
    }

    void ThreeDSurfacePlotWindow::exportSourceDataToLocal()
    {
        QString filter = QObject::tr("CSV Files (*.csv);;Text Files (*.txt)");
        // 打开文件保存对话框，若用户在对话框中选择了文件，则返回对应的文件名
        QString fileName = QFileDialog::getSaveFileName(nullptr,
            QObject::tr("保存文件"),
            "",
            filter);

        // 如果选择为空，则用户可能取消了操作
        if (fileName.isEmpty())
            return;

        auto _isOK = processAndWriteTables(m_graphInfoList, fileName);
        if (_isOK)
        {
            auto _res = IdaDialogMsg::showDialog(nullptr, QStringLiteral("导出数据成功！"), EDialogMsg::Normal, QStringLiteral("成功"), {QStringLiteral("确定")});
            QString tmp = "\"" + fileName + "\"";
            QString pyCode = QString("PostProcessing.exportData(%1)").arg(tmp);
            emit IBaseSignalInstance->signal_execPYCode(QStringList{pyCode}, true, false);
        }
        else
            IBaseSignalInstance->signal_sendErrorMessageToUI("导出数据失败");
    }

    void ThreeDSurfacePlotWindow::pyExportSourceDataToLocal(QString parms)
    {
        processAndWriteTables(m_graphInfoList, parms);
    }

    void ThreeDSurfacePlotWindow::pyCurveNameClicked(QList<int> selectedIndexs)
    {
        m_sidebarSettings->pyCurveNameClicked(selectedIndexs);
    }

    void ThreeDSurfacePlotWindow::pyFrequencyChanged(int index)
    {
        m_sidebarSettings->pyFrequencyChanged(index);
    }

    void ThreeDSurfacePlotWindow::pyResultDataChanged(int index)
    {
        m_sidebarSettings->pyResultDataChanged(index);
    }

    void ThreeDSurfacePlotWindow::pyDataOprationChanged(bool isLoged, bool isNormalized)
    {
        m_sidebarSettings->pyDataOprationChanged(isLoged, isNormalized);
    }

    void ThreeDSurfacePlotWindow::pyItemCheckStateChanged(int itemIndex, bool visible)
    {
        m_sidebarSettings->pyItemCheckStateChanged(itemIndex, visible);
    }

    void ThreeDSurfacePlotWindow::pySaveThreeDSurfacePlotMainSettingData(int settingDataId,
        bool scalarBarIsAutoRange, double scalarBarMin, double scalarBarMax,
        bool scalarBarIsShowTitle, QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
                                                                         int geometryTransparency, QString resultGraphName, int resultGraphModelTransparency, double resultGraphScale, bool cubeAxesIsVisible)
    {
        for (auto i : m_graphInfoList)
        {
            if (i->m_threeDSurfacePlotSettingData->getID() == settingDataId)
            {
                QList<int> _scalarBarFontColor = GlobalHelperInstance->convertStringToIntList(scalarBarFontColor);
                QColor color(_scalarBarFontColor[0], _scalarBarFontColor[1], _scalarBarFontColor[2]);

                auto data = i->m_threeDSurfacePlotSettingData;
                data->getScalarBarSettingData()->setScalarBarAutoRange(scalarBarIsAutoRange);
                data->getScalarBarSettingData()->setScalarBarMinValue(scalarBarMin);
                data->getScalarBarSettingData()->setScalarBarMaxValue(scalarBarMax);
                data->getScalarBarSettingData()->setScalarBarIsShowTitle(scalarBarIsShowTitle);
                data->getScalarBarSettingData()->setScalarBarTitle(scalarBarTitle);
                data->getScalarBarSettingData()->setScalarBarTitleColor(color);
                data->getScalarBarSettingData()->setScalarBarFontSize(scalarBarFontSize);

                if (data->getGeometrySettingData())
                {
                    data->getGeometrySettingData()->setGeometryTransparency(geometryTransparency);
                }

                data->getResultDataSettingData()->setResultDataName(resultGraphName);
                data->getResultDataSettingData()->setResultDataTransparency(resultGraphModelTransparency);
                data->getResultDataSettingData()->setResultDataScaleFactor(resultGraphScale);

                if (data->getCubeAxesActorSettingData())
                {
                    data->getCubeAxesActorSettingData()->setVisibility(cubeAxesIsVisible);
                }

                slot_updateSetting(data);
            }
        }
    }

    void ThreeDSurfacePlotWindow::pySaveThreeDSurfacePlotMoveResultDataSetting(int infomationId, double translationX, double translationY, double translationZ,
        double rotationTheta, double rotationPhi)
    {
        for (const auto& info : m_graphInfoList)
        {
            if (info->m_informationID == infomationId)
            {
                pst::PoseSettingData* data = info->m_poseSettingData;
                data->setTranslationX(translationX);
                data->setTranslationY(translationY);
                data->setTranslationZ(translationZ);
                data->setRotationTheta(rotationTheta);
                data->setRotationPhi(rotationPhi);

                updateActorPosition(info);
                updateClipperPlaneActor();
                updateCubeAxesActor(m_isCubeAxesActorVisible);
                m_renderWindow3D->Render();
            }
        }
    }

    void ThreeDSurfacePlotWindow::pyDelete3DSurfacePlots(QString selectedIndexs)
    {
        m_sidebarSettings->pyDelete3DSurfacePlots(selectedIndexs);
    }

    void ThreeDSurfacePlotWindow::pyThreeDSurfaceCurveNameItemRename(int itemIndex, QString newName)
    {
        auto listWidget = m_sidebarSettings->getCurveNameListWidget();
        QListWidgetItem* item = listWidget->item(itemIndex);
        item->setText(newName);
    }
    void ThreeDSurfacePlotWindow::pyThreeDSurfaceCurveDataFileterRadioButtonClicked(int windowId, int index)
    {
        m_sidebarSettings->pyThreeDSurfaceCurveDataFileterRadioButtonClicked(windowId, index);
    }


    void ThreeDSurfacePlotWindow::slot_scalarBarDoubleClicked(vtkProp* pickedProp)
    { // 使用 pickedProp 进行处理
        if (pickedProp == nullptr)
        {
            return;
        }

        // 只有一个数据
        if (m_graphInfoList.size() == 1)
        {
            if (m_graphInfoList[0]->m_scalarBar == pickedProp)
            {
                auto tmp = m_graphInfoList[0]->m_fieldScalarBarGenerator->getLookupTable()->GetRange();
                m_graphInfoList[0]->m_threeDSurfacePlotSettingData->getScalarBarSettingData()->setScalarBarMinValue(tmp[0]);
                m_graphInfoList[0]->m_threeDSurfacePlotSettingData->getScalarBarSettingData()->setScalarBarMaxValue(tmp[1]);
                m_mainSettingDialog->updateUI(m_graphInfoList[0]->m_threeDSurfacePlotSettingData, ThreeDSurfacePlotSettingDialog::EntryType::ScalarBar);
            }
        }
        // 多个数据
        else
        {
            ThreeDSurfacePlotSettingData* currentData = nullptr;
            for (const auto& i : m_graphInfoList)
            {
                if (i->m_scalarBar == pickedProp)
                {
                    currentData = i->m_threeDSurfacePlotSettingData;
                    auto tmp = i->m_fieldScalarBarGenerator->getLookupTable()->GetRange();
                    i->m_threeDSurfacePlotSettingData->getScalarBarSettingData()->setScalarBarMinValue(tmp[0]);
                    i->m_threeDSurfacePlotSettingData->getScalarBarSettingData()->setScalarBarMaxValue(tmp[1]);
                    //m_mainSettingDialog->updateSettingDataToUI(i.second, ThreeDCloudMapSettingDialog::EntryType::ScalarBar);
                }
            }

            if (isGeometryPathAllSame(m_graphInfoList)) //几何路径全相同
            {
                ThreeDSurfacePlotSettingData* tempData = new ThreeDSurfacePlotSettingData(this, -1);
                tempData->setScalarBarSettingData(currentData->getScalarBarSettingData());
                tempData->setGeometrySettingData(currentData->getGeometrySettingData());
                tempData->setResultDataSettingData(nullptr);
                tempData->setCubeAxesActorSettingData(currentData->getCubeAxesActorSettingData());

                m_mainSettingDialog->updateUI(tempData, ThreeDSurfacePlotSettingDialog::EntryType::ScalarBar);
            }
            else //几何路径不全相同
            {
                ThreeDSurfacePlotSettingData* tempData = new ThreeDSurfacePlotSettingData(this, -1);
                tempData->setScalarBarSettingData(currentData->getScalarBarSettingData());
                tempData->setGeometrySettingData(nullptr);
                tempData->setResultDataSettingData(nullptr);
                tempData->setCubeAxesActorSettingData(currentData->getCubeAxesActorSettingData());

                m_mainSettingDialog->updateUI(tempData, ThreeDSurfacePlotSettingDialog::EntryType::ScalarBar);
            }
        }

        m_mainSettingDialog->execWindow();
    }

    void ThreeDSurfacePlotWindow::initScalarBarSettingConnection()
    {
        connect(m_mainSettingDialog, &ThreeDSurfacePlotSettingDialog::signal_updateSetting,
            this, &ThreeDSurfacePlotWindow::slot_updateSetting);
    }

    void ThreeDSurfacePlotWindow::initSidebarSettingConnection()
    {
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::siganl_showHideItemActor,
            this, &ThreeDSurfacePlotWindow::slot_showHideItemActor);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::siganl_graphNameDoubleClicked,
            this, &ThreeDSurfacePlotWindow::slot_graphNameDoubleClicked);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_chosenItemsChanged,
            this, &ThreeDSurfacePlotWindow::slot_chosenItemsChanged);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_updateActorValue,
            this, &ThreeDSurfacePlotWindow::slot_updateActorOriginalData);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_updateActorOriginalData,
            this, &ThreeDSurfacePlotWindow::slot_updateActorOriginalData);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_deleteChosenGraphs,
            this, &ThreeDSurfacePlotWindow::slot_deleteChosenGraphs);
        connect(m_sidebarSettings, &ThreeDSurfacePlotSidebarSettings::signal_getSidebarCurveDataSource,
            this, &ThreeDSurfacePlotWindow::slot_getSidebarCurveDataSource);
    }

    void ThreeDSurfacePlotWindow::generateSidebarSettingData(QListWidgetItem* item, InfomationGraph3DBasical* info)
    {
        ThreeDSurfacePlotSidebarData* sideBarData = new ThreeDSurfacePlotSidebarData(this);
        info->m_TDSPSidebarData = sideBarData;
        sideBarData->setCurrentFrequencyIndex(info->m_currentFrequencyIndex);
        sideBarData->setCurrentValueGroupNameIndex(info->m_valueGroupNameIndex);
        sideBarData->setCurrentComponentIndex(info->m_valueComponentIndex);
        TextFileParser* reader = static_cast<TextFileParser*>(info->m_reader);
        if (reader == nullptr)
        {
            return;
        }
        QVector<QString> valueNames = reader->getEachColGroupNameOfValue();
        sideBarData->setTextFileParser(reader);
        sideBarData->setValueGroupNameList(valueNames.toList());
        auto m_farFieldGenerator = info->m_farFieldDataGenerator;
        sideBarData->setFrequencyList(m_farFieldGenerator->getFreqencyList());
        sideBarData->setDataSource(info->m_dataSources);

        auto graphName = generateGraphNameAuto(info);
        sideBarData->setGraphName(graphName);
        sideBarData->setIsGraphNameRenamed(false);
    }

    void ThreeDSurfacePlotWindow::connectSignalsAndSlots()
    {
        this->m_renderWindow3D->GetInteractor()->AddObserver(vtkCommand::LeftButtonDoubleClickEvent, m_doubleClickCallback);
    }

    void ThreeDSurfacePlotWindow::disconnectSignalsAndSlots()
    {
        this->m_renderWindow3D->GetInteractor()->RemoveObservers(vtkCommand::LeftButtonDoubleClickEvent);
    }

    void ThreeDSurfacePlotWindow::prepareAnimationData()
    {
        // 准备数据
        // if (!m_isAnimationDataPrepared)
        //{
        for (auto i : m_graphInfoList)
        {
            auto farFieldDataGenerator = i->m_farFieldDataGenerator;
            auto freList = farFieldDataGenerator->getFreqencyList();
            auto valueNameList = farFieldDataGenerator->getValueNameList();

            auto item = i->m_sidebarItem;
            auto sideBarData = i->m_TDSPSidebarData;

            i->m_animationDataList.clear();
            i->m_animationTableList.clear();

            for (int frequencyIndex = 0; frequencyIndex < freList.size(); ++frequencyIndex)
            {
                vtkNew<vtkPolyData> resultData;
                QString errorMsg;
                vtkSmartPointer<vtkTable> table;
                auto isOk = farFieldDataGenerator->getDataSetByFreqency(frequencyIndex, sideBarData->getIsLog(),
                    sideBarData->getIsNormalize(), resultData, i->m_valueGroupNameIndex, errorMsg, table);
                i->m_animationDataList.append(resultData);
                i->m_animationTableList.append(table);
                m_allAnimationdData.append(resultData);
            }
            m_imageSize < i->m_animationDataList.size() ? m_imageSize = i->m_animationDataList.size() : m_imageSize = m_imageSize;
        }
        //}
        // m_isAnimationDataPrepared = true;
    }

    void ThreeDSurfacePlotWindow::updateControlPanel()
    {
        auto chosenItems = m_sidebarSettings->getCurveNameListWidget()->selectedItems();
        if (chosenItems.isEmpty())
        {
            return;
        }
        auto info = getInfoFromSidebarNameItem(chosenItems.at(0));
        ThreeDSurfacePlotSidebarData* data = info->m_TDSPSidebarData;
        m_sidebarSettings->updateInfoValueToUI(data);
    }

    void ThreeDSurfacePlotWindow::animationToNextDataFrame()
    {
        for (auto info : m_graphInfoList)
        {
            auto fieldGraphGenerator = info->m_fieldGraphGenerator;
            if (fieldGraphGenerator == nullptr)
            {
                continue;
            }
            auto& currentFrameID = info->m_currentAnimationIndex;

            if (m_isFirstTimeDataAnimation)//第一次进行数据动图时，始终播放第一帧
            {
                currentFrameID = 0;
                m_isFirstTimeDataAnimation = false;
            }
            else
            {
                int tempID = currentFrameID + m_animationSettingData->sampleRate();
                currentFrameID = tempID >= info->m_animationDataList.size() ? 0 : tempID;
            }
            if (m_isBeginExportAnimation)//是从导出动图启动，始终播放第一帧
            {
                currentFrameID = 0;
                m_isBeginExportAnimation = false;
                m_animationDataCount = 0;
            }
            qDebug() << "currentFrameID: " << currentFrameID;
            fieldGraphGenerator->SetInputDataSet(info->m_animationDataList.at(currentFrameID));

            // 更新频率
            auto freList = info->m_farFieldDataGenerator->getFreqencyList();
            info->m_currentFrequencyIndex = currentFrameID;
            info->m_tableToExport = info->m_animationTableList[currentFrameID];
            auto item = info->m_sidebarItem;
            auto sideBarData = info->m_TDSPSidebarData;
            sideBarData->setCurrentFrequencyIndex(info->m_currentFrequencyIndex);

            //const auto& currentField = info->m_currentScalarArray;
            auto isSetSuccess = fieldGraphGenerator->SetActiveScalarAttribute(
                0, FieldGraphGenerator::StructureType::POINTS, 0); //获取的dataset只有选择的一个场，所以index为0即可
            //info->m_valueIndex, FieldGraphGenerator::StructureType::POINTS, 0);
            if (!isSetSuccess)
            {
                return;
            }
            fieldGraphGenerator->UpdateScalarFieldActor();
            updateControlPanel();

            sentToolBarAnimationDataInfo(info);
        }

        updateMarkerValue();
        updateCubeAxesActor(m_cubeAxesSettingData->getVisibility());
        m_render3D->ResetCameraClippingRange();
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::slot_scalarBarFontTypeChanged(vtkScalarBarActor* scalarBarActor, QString fontType)
    {
        if (scalarBarActor == nullptr)
        {
            return;
        }
        if (fontType == "微软雅黑") // 并非真正的微软雅黑
        {
            QString currenEXEPath = QCoreApplication::applicationDirPath();
            auto micFont = currenEXEPath + "/Fonts/Alibaba-PuHuiTi-Regular.ttf";
            scalarBarActor->GetTitleTextProperty()->SetFontFamily(VTK_FONT_FILE);
            scalarBarActor->GetTitleTextProperty()->SetFontFile(micFont.toLocal8Bit());
        }
        else if (fontType == "宋体") // 并非真正的宋体
        {
            QString currenEXEPath = QCoreApplication::applicationDirPath();
            auto songFont = currenEXEPath + "/Fonts/TangXianBinSong-2.otf";
            scalarBarActor->GetTitleTextProperty()->SetFontFamily(VTK_FONT_FILE);
            scalarBarActor->GetTitleTextProperty()->SetFontFile(songFont.toLocal8Bit());
        }
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::slot_updateSetting(ThreeDSurfacePlotSettingData* data)
    {
        //几何
        auto _geometrySettingData = data->getGeometrySettingData();
        if (_geometrySettingData != nullptr)
        {
            for (const auto& i : m_graphInfoList)
            {
                if (i->m_threeDSurfacePlotSettingData->getGeometrySettingData() == _geometrySettingData)
                {
                    auto info = i;
                    auto _geometryTransparency = _geometrySettingData->getGeometryTransparency();
                    if (info->m_geomtryActorGenerator != nullptr)
                    {
                        info->m_geomtryActorGenerator->getActor()->GetProperty()->SetOpacity(1 - _geometryTransparency / 100.);
                        if (_geometryTransparency == 100)
                        {
                            info->m_geomtryActorGenerator->getActor()->VisibilityOff();
                        }
                        else
                        {
                            info->m_geomtryActorGenerator->getActor()->SetVisibility(m_isShowingGeometry);
                        }
                    }
                    break;
                }
            }
        }

        //结果
        auto _resultSettingData = data->getResultDataSettingData();
        if (_resultSettingData != nullptr)
        {
            for (const auto& i : m_graphInfoList)
            {
                if (i->m_threeDSurfacePlotSettingData->getResultDataSettingData() == _resultSettingData)
                {
                    auto info = i;
                    auto _actorName = _resultSettingData->getResultDataName();
                    auto _transparency = _resultSettingData->getResultDataTransparency();
                    auto _scaleFactor = _resultSettingData->getResultDataScaleFactor();

                    info->m_actor->GetProperty()->SetOpacity(1 - _transparency / 100.);
                    if (_transparency == 100)
                    {
                        info->m_actor->VisibilityOff();
                    }
                    else
                    {
                        auto visbility = info->m_sidebarItem->checkState();
                        
                        info->m_actor->SetVisibility(visbility);
                    }
                    //info->m_actor->SetScale(_scaleFactor);
                    synchronousActorName(info, _actorName);

                    if (info->m_poseSettingData != nullptr)
                    {
                        info->m_poseSettingData->setScaleFactor(_scaleFactor);
                        updateActorPosition(info);
                    }
                    break;
                }
            }
        }

        //包围盒
        if (data->getCubeAxesActorSettingData())
        {
            updateCubeAxesActor(data->getCubeAxesActorSettingData()->getVisibility());
        }

        updateClipperPlaneActor();
        m_render3D->ResetCameraClippingRange();
        m_renderWindow3D->Render();

        // 将颜色条数据回写到对话框
        auto _scalarBarSettingData = data->getScalarBarSettingData();
        if (_scalarBarSettingData != nullptr)
        {
            for (const auto& i : m_graphInfoList)
            {
                if (i->m_threeDSurfacePlotSettingData->getScalarBarSettingData() == _scalarBarSettingData)
                {
                    auto info = i;
                    auto tmp = info->m_fieldScalarBarGenerator->getLookupTable()->GetRange();
                    m_mainSettingDialog->setScalarBarCustomRange(tmp[0], tmp[1]);
                }
            }
        }

    }

    void ThreeDSurfacePlotWindow::slot_showHideItemActor(QListWidgetItem* item)
    {
        if (item == nullptr)
            return;
        InfomationGraph3DBasical* info = getInfoFromSidebarNameItem(item);
        FieldGraphGenerator* fieldGraphGenerator = info->m_fieldGraphGenerator;
        if (fieldGraphGenerator == nullptr)
        {
            qDebug() << "Error: " << __FILE__ << " " << __LINE__ << " Chosen data's generator not exist!";
            return;
        }
        auto dataActor = fieldGraphGenerator->GetScalarsFieldActor();
        if (dataActor == nullptr)
        {
            qDebug() << "Error: " << __FILE__ << " " << __LINE__ << " Data actor is empty!";
            return;
        }

        auto checkState = item->checkState() == Qt::Checked ? true : false;
        info->m_TDSPSidebarData->setIsShowActor(checkState);
        bool markerState = false;

        info->m_fieldGraphGenerator->GetScalarsFieldActor()->SetVisibility(checkState);

        bool isSameTypeAllHide = true;
        for (auto i : m_graphInfoList)
        {
            //判断类型是否相同
            if (info->m_resultType == i->m_resultType)
            {
                if (i->m_fieldGraphGenerator->GetScalarsFieldActor()->GetVisibility())
                {
                    isSameTypeAllHide = false;
                    break;
                }
            }
        }

        info->m_fieldScalarBarGenerator->getScalarBarActor()->SetVisibility(!isSameTypeAllHide);
        info->m_fieldScalarBarGenerator->getScalarBarWidget()->SetEnabled(!isSameTypeAllHide);

        if (m_isActiveClip)//更新数据actor是否显示
        {
            //info->m_fieldGraphGenerator->GetScalarsFieldActor()->SetVisibility(checkState);
            //info->m_fieldGraphGenerator->GetScalarsFieldScalarBarActor()->SetVisibility(checkState);
            //info->m_fieldGraphGenerator->GetScalarsFieldScalarBarWidget()->SetEnabled(checkState);
            markerState = false;
            //if (info->m_dataClipperGenerator != nullptr)
            //{
            //    info->m_dataClipperGenerator->getClipActor()->SetVisibility(checkState);
            //    //m_clipperPlaneActor->SetVisibility(checkState);
            //}
        }
        else
        {
            //info->m_fieldGraphGenerator->GetScalarsFieldActor()->SetVisibility(checkState);
            //info->m_fieldGraphGenerator->GetScalarsFieldScalarBarActor()->SetVisibility(checkState);
            //info->m_fieldGraphGenerator->GetScalarsFieldScalarBarWidget()->SetEnabled(checkState);
            markerState = checkState;
            //if (info->m_dataClipperGenerator != nullptr)
            //{
            //    info->m_dataClipperGenerator->getClipActor()->SetVisibility(false);
            //    //m_clipperPlaneActor->SetVisibility(false);
            //}
        }

        updateClipperPlaneActor();
        updateMarkerValue();
        updateCubeAxesActor(m_cubeAxesSettingData->getVisibility());
        setResetCamera();
    }

    void ThreeDSurfacePlotWindow::slot_graphNameDoubleClicked(QListWidgetItem* item)
    {
        //if (!m_curveMap.contains(item))
        //{
        //    return;
        //}
        InfomationGraph3DBasical* info = getInfoFromSidebarNameItem(item);
        if (info == nullptr) return;

        for (auto i : m_graphInfoList)
        {
            if (i == info)
            {

                ThreeDSurfacePlotSettingData* data = i->m_threeDSurfacePlotSettingData;
                auto tmp = info->m_fieldScalarBarGenerator->getLookupTable()->GetRange();
                data->getScalarBarSettingData()->setScalarBarMinValue(tmp[0]);
                data->getScalarBarSettingData()->setScalarBarMaxValue(tmp[1]);
                m_mainSettingDialog->updateUI(data, ThreeDSurfacePlotSettingDialog::EntryType::ResultData);
            }
        }
        m_mainSettingDialog->execWindow();
    }

    void ThreeDSurfacePlotWindow::slot_updateActorValue(ThreeDSurfacePlotSidebarData* data)
    {
        auto info = getGraph3DInfoFromSidebarData(data);
        auto item = info->m_sidebarItem;
        info->m_valueGroupNameIndex = data->getCurrentValueGroupNameIndex();
        auto fieldGraphGenerator = info->m_fieldGraphGenerator;
        if (fieldGraphGenerator == nullptr)
        {
            qDebug() << "Error: " << __FILE__ << " " << __LINE__ << " Chosen data's generator not exist!";
            return;
        }

        auto isSetSuccess = fieldGraphGenerator->SetActiveScalarAttribute(
            // data->getCurrentValueIndex(), FieldGraphGenerator::StructureType::POINTS, 0);
            0, FieldGraphGenerator::StructureType::POINTS, 0);
        if (!isSetSuccess)
        {
            qDebug() << "Error: " << __FILE__ << " " << __LINE__ << " Set active scalar attribute failed!";
            return;
        }

        // InfomationGraph3DBasical* info2 = m_curveMap[item];

        //for (auto i : m_dataMap)
        //{
        //    if (i.first == info)
        //    {
        //        auto mainSettingData = i.second;
        //        auto scalarBarSetting = mainSettingData->getScalarBarSettingData();
        //        auto range = fieldGraphGenerator->GetCurrentScalarBarRange(FieldGraphGenerator::FieldType::SCALARS);
        //        scalarBarSetting->setScalarBarOriginalMinRange(range[0]);
        //        scalarBarSetting->setScalarBarOriginalMaxRange(range[1]);

        //        if (scalarBarSetting->getScalarBarAutoRange())
        //        {
        //            fieldGraphGenerator->SetScalarBarRange(range[0], range[1], FieldGraphGenerator::FieldType::SCALARS);
        //        }
        //        else
        //        {
        //            auto currentMin = scalarBarSetting->getScalarBarMinValue();
        //            auto currentMax = scalarBarSetting->getScalarBarMaxValue();
        //            fieldGraphGenerator->SetScalarBarRange(currentMin, currentMax, FieldGraphGenerator::FieldType::SCALARS);
        //        }
        //    }
        //}

        if (!info->m_isGraphRenamed)
        {
            auto name = generateGraphNameAuto(info);
            QSignalBlocker bl(m_sidebarSettings->getCurveNameListWidget());
            item->setText(name);
            item->setToolTip(name);

            info->m_name = name;

            for (auto i : m_graphInfoList)
            {
                if (i == info)
                {
                    i->m_threeDSurfacePlotSettingData->getResultDataSettingData()->setResultDataName(name);
                }
            }
        }

        updateMarkerValue();
        updateDBAndUnitData();
        m_render3D->ResetCameraClippingRange();
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::slot_chosenItemsChanged(const QList<QListWidgetItem*>& itemList)
    {
        ThreeDSurfacePlotSidebarData* data = getSidebarDataFromNameItem(itemList.at(0));
        m_sidebarSettings->updateInfoDataAndInterfaceToUI(data);
    }

    void ThreeDSurfacePlotWindow::slot_updateActorOriginalData(ThreeDSurfacePlotSidebarData* idebarData)
    {
        auto parser = idebarData->getTextFileParser();
        auto info = getGraph3DInfoFromSidebarData(idebarData);
        auto item = info->m_sidebarItem;

        auto freIndex = idebarData->getCurrentFrequencyIndex();
        auto valueIndex = idebarData->getCurrentValueGroupNameIndex();
        auto compIndex = idebarData->getCurrentComponentIndex();

        int realIndex = parser->getRealValueIndex(valueIndex, compIndex);
        auto meta = parser->getDataInfoByRealValueIndex(realIndex);
        bool _isLog = false;
        if (meta.resultDataType == 2 || meta.resultDataType == 4)//幅度或标量采用界面设置的log
        {
            _isLog = idebarData->getIsLog();
        }
        auto isNormal = idebarData->getIsNormalize();

        auto m_farFieldGenerator = info->m_farFieldDataGenerator;
        QString errorMsg;
        vtkNew<vtkPolyData> resultData;
        vtkSmartPointer<vtkTable> tableToExport;
        auto isOk = info->m_farFieldDataGenerator->getDataSetByFreqency(freIndex, _isLog,
            isNormal, resultData, realIndex, errorMsg, tableToExport);
        info->m_tableToExport = tableToExport;
        if (!isOk)
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI(errorMsg);
            return;
        }
        m_addedFarFieldData.append(resultData);

        // qDebug() << "resultData = ";
        // resultData->Print(std::cout);

        // info->m_reader = textFileParser;
        // info->m_grapgType = GraphType::ThreeDSurfacePlot;
        // info->m_filePath = textFileParser->GetFileName();
        info->m_data = resultData;
        info->m_currentFrequencyIndex = freIndex;
        info->m_valueGroupNameIndex = valueIndex;
        info->m_valueComponentIndex = compIndex;

        auto fieldGraphGenerator = info->m_fieldGraphGenerator;
        fieldGraphGenerator->SetInputDataSet(resultData);
        fieldGraphGenerator->UpdateScalarFieldActor();

        slot_updateActorValue(idebarData);
        updateDBAndUnitData();
        updateClipper(m_isActiveClip);

        m_render3D->ResetCamera();
        m_render3D->ResetCameraClippingRange();
        vtkCamera* cam = m_render3D->GetActiveCamera();
        double near1 = 1; double far1 = 2;
        cam->GetClippingRange(near1, far1);
        cam->SetClippingRange(near1 * 0.9, far1 * 1.1);
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::slot_updateMathOperation(ThreeDSurfacePlotSidebarData* data)
    {
        auto info = getGraph3DInfoFromSidebarData(data);
        auto item = info->m_sidebarItem;
        // TODO 可以合并到slot_updateActorOriginalData
    }

    void ThreeDSurfacePlotWindow::slot_deleteChosenGraphs(const QList<QListWidgetItem*>& itemList)
    {
        auto curveNameWidget = m_sidebarSettings->getCurveNameListWidget();
        for (QListWidgetItem* item : itemList)
        {
            auto _infoID = getInfoFromSidebarNameItem(item)->m_informationID;
            WindowTotalDataInstance->removeInfomationGraph3DBasicalByID(_infoID);
            //m_sideBarSettingData.remove(item);

            int row = curveNameWidget->row(item);
            if (row != -1)
            {
                m_sidebarSettings->clearControlPlane();//先清除再删除，删除会触发slot_curveNameClicked
                delete curveNameWidget->takeItem(row);
            }
        }

        for (const auto& item : itemList)
        {
            if (item == nullptr)
                return;
            InfomationGraph3DBasical* info = getInfoFromSidebarNameItem(item);

            int count = 0;
            for (const auto& i : m_graphInfoList)
            {
                if (i->m_geometryFileName == info->m_geometryFileName)
                {
                    count++;
                }
            }

            if (count < 2)//是该路径的唯一一个几何体
            {
                if (info->m_geomtryActorGenerator != nullptr)//删除几何体
                {
                    m_render3D->RemoveActor(info->m_geomtryActorGenerator->getActor());

                    //清除设置
                    for (int i = m_geometrySettingTupleList.size() - 1; i >= 0; --i)
                    {
                        if (std::get<0>(m_geometrySettingTupleList[i]) == info->m_geometryFileName)
                        {
                            m_geometrySettingTupleList.removeAt(i);
                        }
                    }
                }
            }

            removeActorWithMarker(info);
            m_graphInfoList.removeOne(info);

            //for (auto i : m_dataMap)
            //{
            //    if (i.first == info)
            //    {
            //        m_dataMap.removeOne(i);
            //        break;
            //    }
            //}
        }

        updateClipperPlaneActor();
        updateCubeAxesActor(m_cubeAxesSettingData->getVisibility());
        updateDBAndUnitData();
        updateModelDisplayAndClipperButtonCheckState();
        updateAnimationButtonState();//放在updateModelDisplayAndClipperButtonCheckState之后

        setResetCamera();
    }

    void ThreeDSurfacePlotWindow::slot_addCustomContextMenu(const QPoint& pos)
    {
    }

    void ThreeDSurfacePlotWindow::slot_rightButtonUpEvent(const QPoint& globalPos, vtkActor* pickedActor)
    {
        if (pickedActor == nullptr)
        {
            //TODO 空白处右键菜单
            return;
        }

        QMenu menu(this);
        auto action = menu.addAction("移动结果图位置");

        connect(action, &QAction::triggered, this, [this, pickedActor]()
            {
                for (auto info : m_graphInfoList)
                {
                    if (info->m_actor == pickedActor)
                    {
                        PoseSettingDialog* poseSettingDialog = new PoseSettingDialog(this);
                        poseSettingDialog->updateSetting(info);
                        poseSettingDialog->showWindow();

                        connect(poseSettingDialog, &PoseSettingDialog::signal_updateActorPose,
                            this, [this, info]()
                            {
                                updateActorPosition(info);
                                updateClipperPlaneActor();
                                updateCubeAxesActor(m_isCubeAxesActorVisible);
                                m_renderWindow3D->Render();
                            });
                    }
                }
            });


        for (auto info : m_graphInfoList)
        {
            if (info->m_actor == pickedActor)
            {
                menu.exec(globalPos);
                break;
            }
        }
    }

    void ThreeDSurfacePlotWindow::slot_getSidebarCurveDataSource(QListWidgetItem* item, QString& dataSource)
    {
        InfomationGraph3DBasical* info = getInfoFromSidebarNameItem(item);
        if (info != nullptr)
        {
            emit IWidgetSignalInstance->signal_getThreeDDataSources(info->m_reader, dataSource);
        }
    }

    bool ThreeDSurfacePlotWindow::processAndWriteTables(QList<InfomationGraph3DBasical*> infoList,
        const QString& outputFilename)
    {
        QFile file(outputFilename);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            qDebug() << "Unable to open file " << outputFilename;
            return false;
        }

        QTextStream out(&file);

        // 遍历每个 table
        for (int i = 0; i < infoList.size(); ++i)
        {
            auto info = infoList[i];
            vtkNew<vtkTable> table;
            table->DeepCopy(info->m_tableToExport);

            // 针对方向图数据做的theta90度偏移，使导出的数据与原始数据一致（与显示数据差90度）
            auto thetaColumn = vtkDoubleArray::SafeDownCast(table->GetColumn(0));
            auto rowNum = info->m_tableToExport->GetNumberOfRows();
            for (int i = 0; i < rowNum; ++i)
            {
                thetaColumn->SetValue(i, 90 - thetaColumn->GetValue(i));
            }

            int frequencyIndex = info->m_currentFrequencyIndex;
            int valueIndex = info->m_valueGroupNameIndex;

            auto freList = info->m_farFieldDataGenerator->getFreqencyList();

            // 提取 HeadComment 字段内容，作为该 table 的第一行输出
            vtkStringArray* headCommentArray = vtkStringArray::SafeDownCast(table->GetFieldData()->GetAbstractArray("HeadComment"));
            if (!headCommentArray || headCommentArray->GetNumberOfValues() == 0)
            {
                qDebug() << "Table " << i << " has no ‘HeadComment’.";
                continue;
            }
            QString headComment = QString::fromStdString(headCommentArray->GetValue(0));
            out << headComment << "\n";

            //提取表格Header
            vtkStringArray* headerArray = vtkStringArray::SafeDownCast(table->GetFieldData()->GetAbstractArray("Header"));
            if (!headerArray || headerArray->GetNumberOfValues() == 0)
            {
                qDebug() << "Table " << i << " has no 'headerArray'.";
                continue;
            }
            QString header = QString::fromStdString(headerArray->GetValue(0));
            QString frequencyStr = header.section(',', 0, 0).trimmed();

            // 生成新的 processedTable：先插入 Frequency 列
            vtkSmartPointer<vtkTable> processedTable = vtkSmartPointer<vtkTable>::New();
            vtkSmartPointer<vtkDoubleArray> frequencyColumn = vtkSmartPointer<vtkDoubleArray>::New();
            frequencyColumn->SetName(frequencyStr.toStdString().c_str());
            vtkIdType numRows = table->GetNumberOfRows();
            frequencyColumn->SetNumberOfTuples(numRows);
            for (vtkIdType row = 0; row < numRows; ++row)
            {
                frequencyColumn->SetValue(row, freList[frequencyIndex]);
            }
            processedTable->AddColumn(frequencyColumn);

            for (int colIndex = 0; colIndex < 2; ++colIndex)
            {
                if (colIndex < table->GetNumberOfColumns())
                {
                    vtkAbstractArray* col = table->GetColumn(colIndex);
                    processedTable->AddColumn(col);
                }
            }
            // 添加原 table 的第2 + valueIndex列，需确保列数足够
            if (table->GetNumberOfColumns() > 2 + valueIndex)
            {
                vtkAbstractArray* col = table->GetColumn(2 + valueIndex);
                processedTable->AddColumn(col);
            }
            else
            {
                qDebug() << "Table col number is not enough!";
            }

            // 写入表头（列名称），列之间使用逗号分隔
            QStringList headers;
            for (int col = 0; col < processedTable->GetNumberOfColumns(); ++col)
            {
                QString colName = QString::fromStdString(processedTable->GetColumnName(col));
                headers << colName;
            }
            out << headers.join(",") << "\n";

            // 写入数据行，每行数据各字段间以逗号分隔
            for (vtkIdType row = 0; row < processedTable->GetNumberOfRows(); ++row)
            {
                QStringList rowValues;
                for (int col = 0; col < processedTable->GetNumberOfColumns(); ++col)
                {
                    vtkVariant val = processedTable->GetValue(row, col);
                    rowValues << QString::fromStdString(val.ToString());
                }
                out << rowValues.join(",") << "\n";
            }

            // 每个 table 输出完后增加两行空白（用于区分不同的 table）
            if (i < infoList.size() - 1)
            {
                out << "\n\n";
            }
        }

        file.close();
        //qDebug() << "文件写入完成: " << outputFilename;
        return true;
    }

    void ThreeDSurfacePlotWindow::removeActorWithMarker(InfomationGraph3DBasical* info)
    {
        FieldGraphGenerator* fieldGraphGenerator = info->m_fieldGraphGenerator;
        if (fieldGraphGenerator == nullptr)
        {
            qDebug() << "Error: " << __FILE__ << " " << __LINE__ << " Chosen data's generator not exist!";
            return;
        }
        auto actor = fieldGraphGenerator->GetScalarsFieldActor();
        auto scalarBaractor = info->m_scalarBar;
        auto scalarBarWidget = info->m_fieldScalarBarGenerator->getScalarBarWidget();
        info->m_fieldScalarBarGenerator->removeAGraph(fieldGraphGenerator);
        //auto clipperGerator = info->m_dataClipperGenerator;
        QList< Marker3DDataInfo*> toDeleteList;
        QList<int> toDeleteTableIndexs;
        auto innerMatrkerTable = m_markerDataTable->getInnerTableWidget();

        for (const auto& i : m_marker3DDataInfoList)
        {
            if (i->m_sourceActor == actor)
            {
                m_render3D->RemoveActor(i->m_markerActor);
                m_render3D->RemoveActor(i->m_markerTextActor);

                //同步markerTable可见性
                for (int row = 0; row < innerMatrkerTable->rowCount(); ++row)
                {
                    if (innerMatrkerTable->item(row, 0)->text().toInt() == i->m_markerId)
                    {
                        toDeleteTableIndexs.append(row);
                    }
                }
                toDeleteList.append(i);
            }

        }
        for (const auto& i : toDeleteList)
        {
            int key = m_marker3DDataInfoList.key(i);
            m_marker3DDataInfoList.remove(key);
        }
        std::sort(toDeleteTableIndexs.begin(), toDeleteTableIndexs.end());
        for (int i = toDeleteTableIndexs.size() - 1; i >= 0; --i)
        {
            innerMatrkerTable->removeRow(toDeleteTableIndexs.at(i));
        }
        if (innerMatrkerTable->rowCount() == 0)
        {
            m_markerDataTable->hide();
        }
        m_render3D->RemoveActor(actor);

        bool leftSameType = false;//是否还有同类型的actor存在
        for (auto i : m_graphInfoList)
        {
            if (i == info)
            {
                continue;
            }

            //判断类型是否相同
            if (info->m_resultType == i->m_resultType)
            {
                leftSameType = true;
                break;
            }
        }

        if (!leftSameType)
        {
            m_render3D->RemoveActor(scalarBaractor);
            scalarBarWidget->SetEnabled(false);
        }

        qDebug() << "info->m_scalarBar = " << info->m_scalarBar;
        //if (clipperGerator != nullptr)
        //{
        //    m_render3D->RemoveActor(clipperGerator->getClipActor());
        //}
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::updateMarkerValue()
    {
        auto tableWidget = m_markerDataTable->getInnerTableWidget();
        for (int i = 0; i < tableWidget->rowCount(); ++i)
        {
            //不显示的不更新，不显示包括（可见性为false和显示类型不同）
            //因此更新actor可见性时，需要调用本函数
            if (tableWidget->isRowHidden(i))
            {
                continue;
            }

            int markerId = tableWidget->item(i, 0)->text().toInt();
            Marker3DDataInfo* markerInfo = m_marker3DDataInfoList.value(markerId);
            if (markerInfo == nullptr)
            {
                continue;
            }

            auto dataSet = markerInfo->m_sourceActor->GetMapper()->GetInput();
            if (!dataSet)
            {
                return;
            }

            auto curveNameWidget = m_sidebarSettings->getCurveNameListWidget();
            for (int row = 0; row < curveNameWidget->count(); ++row)
            {
                QListWidgetItem* item = curveNameWidget->item(row);
                auto graphInfo = getInfoFromSidebarNameItem(item);
                FieldGraphGenerator::ArrayInformation currentArray = graphInfo->m_currentScalarArray;

                if (currentArray.type == FieldGraphGenerator::StructureType::POINTS)//当前激活的场是cell
                {
                    if (markerInfo->m_markerType == 0)
                    {
                        auto activeArray = dataSet->GetPointData()->GetScalars();
                        QString pickedValue = "null";
                        if (activeArray != nullptr)//原数据有激活point场
                        {
                            if (markerInfo->m_pickedId < dataSet->GetNumberOfPoints())
                            {
                                double value = activeArray->GetComponent(markerInfo->m_pickedId, 0);
                                pickedValue = QString::number(value);

                                tableWidget->item(i, 4)->setText(QString::number(value));
                                markerInfo->m_markerValue = value;
                            }
                            else
                            {
                                qDebug() << "Error:currentPointId is out of range";
                            }
                        }
                    }
                    else
                    {
                        tableWidget->item(i, 4)->setText("null");
                        markerInfo->m_markerValue = "null";
                    }
                }
                else //当前激活的场是cell
                {
                    if (markerInfo->m_markerType == 1)
                    {
                        auto activeArray = dataSet->GetCellData()->GetScalars();
                        QString pickedValue = "null";
                        if (activeArray != nullptr)//原数据有激活cell场
                        {
                            if (markerInfo->m_pickedId < dataSet->GetNumberOfCells())
                            {
                                double value = activeArray->GetComponent(markerInfo->m_pickedId, 0);
                                pickedValue = QString::number(value);

                                tableWidget->item(i, 4)->setText(QString::number(value));
                                markerInfo->m_markerValue = value;
                            }
                            else
                            {
                                qDebug() << "Error:currentPointId is out of range";
                            }
                        }
                    }
                    else
                    {
                        tableWidget->item(i, 4)->setText("null");
                        markerInfo->m_markerValue = "null";
                    }
                }
            }
        }
    }

    void ThreeDSurfacePlotWindow::setInteractorStlyleToTranslation()
    {
        m_defaultInteractorStyle->setInnerInteractionStyle(1);
    }

    void ThreeDSurfacePlotWindow::setInteractorStlyleToRotation()
    {
        m_defaultInteractorStyle->setInnerInteractionStyle(0);
    }

    void ThreeDSurfacePlotWindow::setInteractorStlyleToDefault()
    {
        m_defaultInteractorStyle->setInnerInteractionStyle(0);
        //m_defaultInteractorStyle->SetDefaultRenderer(m_render3D);
        //m_defaultInteractorStyle->SetRenderWindowWidget(m_qvtkWidget);
        //m_renderWindow3D->GetInteractor()->SetInteractorStyle(m_defaultInteractorStyle);
        //m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::updateActorPosition(InfomationGraph3DBasical* info)
    {
        auto pipeLineManager = info->m_fieldGraphGenerator->GetScalarPipelineManager();
        if (info->m_dataTransformFilter == nullptr)
        {
            info->m_dataTransformFilter = new DataTransformFilter();
            pipeLineManager->AddFilter("Transform", info->m_dataTransformFilter);
        }
        info->m_dataTransformFilter->setPoseSettingData(info->m_poseSettingData);
        info->m_fieldGraphGenerator->UpdateScalarFieldActor();

        m_render3D->ResetCameraClippingRange();
        m_renderWindow3D->Render();
    }

    bool ThreeDSurfacePlotWindow::isInfoContainsMultipleData(const InfomationGraph3DBasical* info)
    {
        auto farFieldDataGenerator = info->m_farFieldDataGenerator;
        auto freList = farFieldDataGenerator->getFreqencyList();

        return freList.size() > 1;
    }

    bool ThreeDSurfacePlotWindow::isInfoFromSameSource(QList<InfomationGraph3DBasical*> infoList)
    {
        if (infoList.isEmpty())
        {
            return false;
        }

        QString _filePath{ "" };
        int count = 0;
        for (const auto& info : infoList)
        {
            QString filePath = info->m_filePath;
            if (filePath.isEmpty())
            {
                return false;
            }

            if (count == 0)
            {
                _filePath = filePath;
                ++count;
                continue;
            }

            if (_filePath != filePath)
            {
                return false; // 如果有任意一个信息的文件路径不同，则返回false
            }
        }
        return true;
    }

    bool ThreeDSurfacePlotWindow::whetherCanEnableDataAnimation()
    {
        if (m_graphInfoList.size() != 1)
        {
            return false;
        }

        return isInfoContainsMultipleData(m_graphInfoList[0]) ? true : false;
    }

    void ThreeDSurfacePlotWindow::updateDBAndUnitData()
    {
        QSet<int> typeProcessed;
        for (auto i : m_graphInfoList)
        {
            auto info = i;
            auto settingData = i->m_threeDSurfacePlotSettingData;

            //以侧边栏同类型的第一个数据为准
            if (typeProcessed.contains(info->m_resultType))
            {
                continue;
            }
            typeProcessed.insert(info->m_resultType);

            auto reader = static_cast<TextFileParser*>(info->m_reader);

            int groupValueIndex = info->m_valueGroupNameIndex;
            int componentValueIndex = info->m_valueComponentIndex;
            int realIndex = reader->getRealValueIndex(groupValueIndex, componentValueIndex);
            auto meta = reader->getDataInfoByRealValueIndex(realIndex);
            auto unit = meta.unit;//单位
            unit.toUpper() == "NONE" ? unit = "" : unit;

            auto item = info->m_sidebarItem;
            auto sideBarSettingData = getSidebarDataFromNameItem(item);
            bool _isLog = false;
            if (meta.resultDataType == 2 || meta.resultDataType == 4)//幅度或标量采用界面设置的log
            {
                _isLog = sideBarSettingData->getIsLog();
            }

            auto sliderBarSettingData = i->m_threeDSurfacePlotSettingData->getScalarBarSettingData();
            sliderBarSettingData->setScalarBarUnit(unit);
            sliderBarSettingData->setScalarBarIsLog(_isLog);
        }
    }

    void ThreeDSurfacePlotWindow::sentToolBarAnimationDataInfo(const InfomationGraph3DBasical* info)
    {
        auto& currentFrameID = info->m_currentAnimationIndex;
        //右上角显示动图信息
        auto _type = info->m_fieldType;
        auto unit = info->m_unit;
        auto varValueList = info->m_VarValueList;
        QString typeString{};

        if (m_animationType == 0)//数据变换
        {
            //if (_type == 1)
            //{
            //    typeString = "时间";
            //}
            //else if (_type == 2)
            //{
            typeString = "频率";//三维曲面图数据变化始终是频率
            //}
        }
        else //相机
        {
            typeString = "角度";
            unit = "deg";
        }

        auto currentValue = varValueList[currentFrameID];
        QString firstLine = typeString + ": " + QString::number(currentValue) + " " + unit;

        auto sameRate = m_animationSettingData->sampleRate();
        QString secondLine = "采样率: " + QString::number(sameRate);

        auto frameRate = m_animationSettingData->frameRate();
        QString thirdLine = "播放速度: " + QString::number(frameRate);

        QStringList textActorList;
        textActorList << firstLine << secondLine << thirdLine;
        setAnimationInfoText(textActorList);

        int totalNum = std::ceil(double(info->m_animationDataList.size()) / sameRate);

        if (m_animationDataCount * sameRate >= info->m_animationDataList.size())
        {
            m_animationDataCount = 0;
        }

        if (m_animationTooBarInfoData != nullptr)
        {
            m_animationTooBarInfoData->setType(typeString);
            m_animationTooBarInfoData->setUnit(unit);
            m_animationTooBarInfoData->setCurrentValue(QString::number(currentValue));
            m_animationTooBarInfoData->setSliderCurrentValue(currentFrameID);
            m_animationTooBarInfoData->setSliderMaxValue(totalNum);
        }

        emit IWidgetSignalInstance->signal_setToolBarAnimationDataInfo(typeString, unit, currentValue, totalNum, m_animationDataCount);
        ++m_animationDataCount;
    }

    QString ThreeDSurfacePlotWindow::generateGraphNameAuto(InfomationGraph3DBasical* info) const
    {
        QString graphName;

        auto fileType = info->m_resultType;
        auto graphId = info->m_graphIDFromType;

        auto groupIndex = info->m_valueGroupNameIndex;
        auto compIndex = info->m_valueComponentIndex;
        auto parser = static_cast<TextFileParser*> (info->m_reader);
        if (parser == nullptr)
        {
            return graphName;
        }
        auto realValueIndex = parser->getRealValueIndex(groupIndex, compIndex);
        auto metaInfo = parser->getDataInfoByRealValueIndex(realValueIndex);
        auto groupName = metaInfo.dataGroupName;
        auto compoType = metaInfo.resultDataType;

        QString arrayName;
        switch (compoType)//0:实部, 1 : 虚部, 2 : 幅度, 3 : 相位 4 : 标量
        {
        case 0:
            arrayName = "Re(" + groupName + ")";
            break;
        case 1:
            arrayName = "Im(" + groupName + ")";
            break;
        case 2:
            arrayName = "mag(" + groupName + ")";
            break;
        case 3:
            arrayName = "arg(" + groupName + ")";
            break;
        case 4:
            arrayName = groupName;
            break;
        }

        auto typeString = GetResultDataTypeAsString(fileType, false);
        if (arrayName.isEmpty())
        {
            graphName = typeString + "_" + QString::number(graphId);
        }
        else
        {
            graphName = typeString + "_" + QString::number(graphId) + "[" + arrayName + "]";
        }
        return graphName;
    }

    ThreeDSurfacePlotSettingData* ThreeDSurfacePlotWindow::getMainSettingData(InfomationGraph3DBasical* info)
    {
        for (auto i : m_graphInfoList)
        {
            if (i == info)
            {
                return i->m_threeDSurfacePlotSettingData;
            }
        }
    }

    ThreeDSurfacePlotSidebarData* ThreeDSurfacePlotWindow::getSidebarDataFromNameItem(QListWidgetItem* item)
    {
        for(auto i : m_graphInfoList)
        {
            if (i->m_sidebarItem == item)
            {
                return i->m_TDSPSidebarData;
            }
        }
        return nullptr;
    }

    InfomationGraph3DBasical* ThreeDSurfacePlotWindow::getGraph3DInfoFromSidebarData(ThreeDSurfacePlotSidebarData* data)
    {
        for(auto i : m_graphInfoList)
        {
            if (i->m_TDSPSidebarData == data)
            {
                return i;
            }
        }
        return nullptr;
    }

    void ThreeDSurfacePlotWindow::updateGeometryActors(bool isShow, bool& hasAnyGeometrySuccess)
    {
        bool _hasAnyGeometry = false;
        m_isShowingGeometry = isShow;
        QList<QStringList> m_updatedList;

        for (auto info : m_graphInfoList)
        {
            const auto& path = info->m_geometryFileName;
            if (path.empty())
            {
                continue;
            }

            //auto isAdded = info->m_isGeomtryActorImported;
            //auto geometryActor = info->m_geometryActor;
            if (isShow)
            {
                if (m_updatedList.contains(path))
                {
                    continue;
                }

                //if (info->m_geomtryActorGenerator == nullptr)
                //{
                //    GeomtryActorGenerator* generator = new GeomtryActorGenerator(this);
                //    generator->setFileNameList(path);
                //    //generator->setIsActiveClip(m_isActiveClip);
                //    //generator->setClipPlaneNormalDirection(m_planeNormalDirection);
                //    //generator->setClipPlaneOrigin(m_planeOrigin);
                //    //generator->updateActor();
                //    info->m_geomtryActorGenerator = generator;
                //    //info->m_geometryActor = generator->getActor();
                //    m_render3D->AddActor(generator->getActor());
                //}

                m_updatedList.append(path);

                info->m_geomtryActorGenerator->setIsActiveClip(m_isActiveClip);
                info->m_geomtryActorGenerator->setClipPlaneNormalDirection(m_planeNormalDirection);
                info->m_geomtryActorGenerator->setClipPlaneOrigin(m_planeOrigin);
                int status = info->m_geomtryActorGenerator->updateActor();
                if (status == 2)//全部失败的情况
                {
                    //QString _errorText = info->m_geomtryActorGenerator->getErrorMessage();
                    //emit IBaseSignalInstance->signal_sendErrorMessageToUI(_errorText);
                    //delete info->m_geomtryActorGenerator;
                    //info->m_geomtryActorGenerator = nullptr;
                    continue;
                }
                //else if (status == 1)//部分失败的情况，继续执行
                //{
                //    QString _errorText = info->m_geomtryActorGenerator->getErrorMessage();
                //    emit IBaseSignalInstance->signal_sendErrorMessageToUI(_errorText);
                //}

                auto centerSetting = getMainSettingData(info);
                int tranceparency = centerSetting->getGeometrySettingData()->getGeometryTransparency();

                if (tranceparency == 100)//全部透明的情况
                {
                    info->m_geomtryActorGenerator->getActor()->SetVisibility(false);

                }
                else
                {
                    info->m_geomtryActorGenerator->getActor()->SetVisibility(true);
                }

                m_render3D->AddActor(info->m_geomtryActorGenerator->getActor());
                _hasAnyGeometry = true;
            }
            else
            {
                if (info->m_geomtryActorGenerator != nullptr)
                {
                    info->m_geomtryActorGenerator->getActor()->SetVisibility(0);
                    _hasAnyGeometry = true;
                }
            }
        }

        if (isShow && !_hasAnyGeometry)//全部失败的情况
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI("未读取到有效几何文件");
            m_isShowingGeometry = false;//没有几何文件导入成功的情况下，要将显示状态设为false,同时显示模型的按钮设置为未选中
        }
        hasAnyGeometrySuccess = _hasAnyGeometry;

        m_render3D->ResetCameraClippingRange();
        m_renderWindow3D->Render();
    }

    void ThreeDSurfacePlotWindow::slot_renameCheck()
    {
        auto listWidget = m_sidebarSettings->getCurveNameListWidget();
        auto selectedItems = listWidget->selectedItems();
        if (selectedItems.size() != 1)
        {
            return;
        }
        auto item = selectedItems[0];
        auto info = getInfoFromSidebarNameItem(item);
        //auto graph = qobject_cast<QCPGraph*>(info->getCurveLineAddress());

        if (item->text().isEmpty())
        {
            EDialogMsgResult _result = IdaDialogMsg::showDialog(this, QString("命名不能为空，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
            item->setText(info->m_name);
            return;
        }

        for (auto i: m_graphInfoList)
        {
            auto tmpItem = i->m_sidebarItem;
            if (tmpItem == item)
            {
                continue;
            }
            if (item->text() == tmpItem->text())
            {
                EDialogMsgResult _result = IdaDialogMsg::showDialog(this, QString("当前名称已存在，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
                item->setText(info->m_name);
                return;
            }
        }
        info->m_isGraphRenamed = true;
        synchronousActorName(info, item->text());

        QStringList _pyCodes{};
        QString newName = "'" + item->text() + "'";
        _pyCodes += QString("sidebarsettingspy = PostProcessing.ThreeDSurfacePlotSidebarSettingsPy()");
        _pyCodes += QString("sidebarsettingspy.threeDSurfaceCurveNameItemRename(%1,%2,%3)").arg(m_windowId).arg(listWidget->row(item)).arg(newName);
        emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
    }

    bool ThreeDSurfacePlotWindow::slot_checkResultNameIsValid(ThreeDSurfacePlotSettingData* data, const QString& newName)
    {
        if (newName.isEmpty())
        {
            EDialogMsgResult _result = IdaDialogMsg::showDialog(this, QString("命名不能为空，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
            return false;
        }

        for (auto i : m_graphInfoList)
        {
            if (i->m_threeDSurfacePlotSettingData == data)
            {
                continue;
            }
            if (i->m_threeDSurfacePlotSettingData->getResultDataSettingData()->getResultDataName() == newName)
            {
                EDialogMsgResult _result = IdaDialogMsg::showDialog(this, QString("当前名称已存在，请重新编辑。"), EDialogMsg::Error, tr("重命名错误"));
                return false;
            }
        }

        for (auto i : m_graphInfoList)
        {
            if (i->m_threeDSurfacePlotSettingData == data && i->m_name != newName)//是重命名
            {
                i->m_isGraphRenamed = true;
                break;
            }
        }

        return true;
    }

    void ThreeDSurfacePlotWindow::synchronousActorName(InfomationGraph3DBasical* info, const QString& newName)
    {
        if (info == nullptr)
        {
            return;
        }

        auto item = info->m_sidebarItem;
        if (item == nullptr)
        {
            return;
        }

        QSignalBlocker bl(m_sidebarSettings->getCurveNameListWidget());
        item->setText(newName);
        item->setToolTip(newName);

        info->m_name = newName;

        auto sidebarSetting = getSidebarDataFromNameItem(item);
        if (sidebarSetting != nullptr)
        {
            sidebarSetting->setGraphName(newName);
            sidebarSetting->setIsGraphNameRenamed(true);
        }

        auto mainSetting = getMainSettingData(info);
        if (mainSetting != nullptr)
        {
            mainSetting->getResultDataSettingData()->setResultDataName(newName);
        }
    }

    void ThreeDSurfacePlotWindow::slot_closeTree(const QList<QStandardItem*>& items)
    {
        QList<QListWidgetItem*> itemToDelete;
        for (auto treeItem : items)
        {
            for (auto info : m_graphInfoList)
            {
                if (info->m_projectTreeSourceItem == treeItem)
                {
                    auto sidebarItem = info->m_sidebarItem;
                    itemToDelete.append(sidebarItem);
                }
            }
        }
        slot_deleteChosenGraphs(itemToDelete);
    }

} // namespace pst 
